//
//  ApConfigManager.m
//  sHome
//
//  Created by tracyhenry on 2022/5/27.
//  Copyright © 2022 Siterwell. All rights reserved.
//

//error: 0  成功
//       60-61 设备未进入AP配网模式
//       51 网络问题，WIFI未打开

#import "ApConfigManager.h"
#import "AppStatusHelp.h"
#import "GCDAsyncSocket.h"
#import "Single.h"
#import "DebugInfo.h"
#import "TimeHelper.h"
#import "ToolBox.h"
#import "NVLogManager.h"
#define Ap_Config_Host @"192.168.4.1"
#define Ap_Config_Port 8023
#define AP_Shake_Step_1 @65535
#define AP_Shake_Step_2 @65534

@interface ApConfigManager()<GCDAsyncSocketDelegate>
@property(nonatomic,strong) GCDAsyncSocket *clientSocket;
@property(nonatomic,copy)  NSString * wifi;
@property(nonatomic,copy) NSString * pwd;
@property(nonatomic,strong) void(^isConnectCallback)(void);
@property(nonatomic,strong) void(^Callback)(NSError *error,NSDictionary *data);
@property(nonatomic,strong) NSTimer *timer_connect;
@property(nonatomic,assign) long count;
@end

@implementation ApConfigManager

#pragma mark -life
- (instancetype)init{
    if (self = [super init]) {
        self.clientSocket = [[GCDAsyncSocket alloc]initWithDelegate:self delegateQueue:dispatch_get_main_queue()];
    }
    return self;
}


#pragma mark -method
-(void)connect:(NSString *) wifi witWifiPwd:(NSString *)pwd connectCallback:(void(^)(void)) connectCallback Callback:(void(^)(NSError *error,NSDictionary *data)) callback{
    self.wifi = wifi;
    self.pwd = pwd;
    self.isConnectCallback=connectCallback;
    self.Callback = callback;
    NSError * error = nil;
    if(wifi.length>20 || pwd.length>20){
        NSError *error = [[NSError alloc] initWithDomain:NSCocoaErrorDomain code:100 userInfo:nil];
        self.Callback(error, nil);
    }else{
        [self.clientSocket connectToHost:Ap_Config_Host onPort:Ap_Config_Port  error:&error];
        [self startTimer];
    }

}

-(void)startTimer{
    self.count = 0;
    if(_timer_connect!=nil){
        [_timer_connect invalidate];
    }
    _timer_connect = [NSTimer scheduledTimerWithTimeInterval:3 target:self selector:@selector(runTimer) userInfo:nil repeats:YES];
    [[NSRunLoop currentRunLoop] addTimer:_timer_connect forMode:UITrackingRunLoopMode];
}

-(void)runTimer{
    self.count++;
    if(self.count<10){
        NSError * error = nil;
        [self.clientSocket connectToHost:Ap_Config_Host onPort:Ap_Config_Port  error:&error];
    }else{
        NSError *error = [[NSError alloc] initWithDomain:NSCocoaErrorDomain code:61 userInfo:nil];
        self.Callback(error, nil);
        self.count = 0;
        if(_timer_connect!=nil){
            [_timer_connect invalidate];
        }
    }
}

-(void)writeString:(NSString *)str{
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    
    
    DebugInfo *debugInfo = [[DebugInfo alloc] init];
    [debugInfo setIsSend:YES];
    [debugInfo setTime:[TimeHelper getCurrentTimes]];
    [debugInfo setContent:str];
    [[ToolBox sharedToolBox] addDebugLog:debugInfo];
    
    [self.clientSocket writeData:data withTimeout:-1 tag:0];
}

-(void)writeDict:(NSDictionary *)dict{
    NSString *str = [self convertToJsonData:dict];
    
    DebugInfo *debugInfo = [[DebugInfo alloc] init];
    [debugInfo setIsSend:YES];
    [debugInfo setTime:[TimeHelper getCurrentTimes]];
    [debugInfo setContent:str];
    [[ToolBox sharedToolBox] addDebugLog:debugInfo];
    
    NSData *data = [str dataUsingEncoding:NSUTF8StringEncoding];
    [self.clientSocket writeData:data withTimeout:-1 tag:0];
}

-(void)disconnect{
    [self.clientSocket disconnect];
}

-(NSString *)convertToJsonData:(NSDictionary *)dict{
    NSError *error;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
    NSString *jsonString;
    
    if (!jsonData) {
        NVLogInfo(@"%@",error);
    }else{
        jsonString = [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
    }
    NSMutableString *mutStr = [NSMutableString stringWithString:jsonString];
    
    NSRange range = {0,jsonString.length};
    
    [mutStr replaceOccurrencesOfString:@" " withString:@"" options:NSLiteralSearch range:range];
    NSRange range2 = {0,mutStr.length};
    [mutStr replaceOccurrencesOfString:@"\n" withString:@"" options:NSLiteralSearch range:range2];
    return mutStr;
    
}

#pragma mark -delegate
-(void)socket:(GCDAsyncSocket *)sock didConnectToHost:(NSString *)host port:(uint16_t)port{
    
    self.count = 0;
    if(_timer_connect!=nil){
        [_timer_connect invalidate];
    }
    
    if(self.isConnectCallback!=nil)
    self.isConnectCallback();
    [self.clientSocket readDataWithTimeout:-1 tag:0];
    NSTimeZone* destinationTimeZone = [NSTimeZone localTimeZone] ;///获取当前时区信息
    NSInteger sourceGMTOffset = [destinationTimeZone secondsFromGMTForDate:[NSDate date]];///获取偏移秒数
   NSInteger _zoneOffset = sourceGMTOffset/3600;
    _zoneOffset = _zoneOffset > 0 ? _zoneOffset : 256 + _zoneOffset;
    int msg_id = [Single sharedInstanced].msg_id;
    [self writeDict:@{@"namespace":@"config",@"source":@"app",@"target":@"gateway",@"hw_id":@"NULL",@"msg_id":@(msg_id),@"msg":@{@"CMD_CODE":AP_Shake_Step_1,@"str1":self.wifi,@"str2":self.pwd,@"str3":@"0800"}}];
    [Single sharedInstanced].msg_id++;
    
}

-(void)socketDidDisconnect:(GCDAsyncSocket *)sock withError:(NSError *)err{
    
    self.count = 0;
    if(_timer_connect!=nil){
        [_timer_connect invalidate];
    }
    
    if(self.Callback!=nil){
        self.Callback(err,nil);
        [self myRelease];
    }
}


-(void)socket:(GCDAsyncSocket *)sock didReadData:(NSData *)data withTag:(long)tag{
    [self.clientSocket readDataWithTimeout:-1 tag:0];
    NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:data
                                                        options:NSJSONReadingMutableLeaves
                                                          error:nil];
    
    if(dic==nil){
        return;
    }
    
    self.count = 0;
    if(_timer_connect!=nil){
        [_timer_connect invalidate];
    }
    
    NSString *str = [self convertToJsonData:dic];
    DebugInfo *debugInfo = [[DebugInfo alloc] init];
    [debugInfo setTime:[TimeHelper getCurrentTimes]];
    [debugInfo setContent:str];
    [[ToolBox sharedToolBox] addDebugLog:debugInfo];
    
    if(self.Callback!=nil){
        self.Callback(nil,dic);
        
        NSString *str3 =  dic[@"msg"][@"str3"];
        NSString *deviceId =  dic[@"hw_id"];

        if([@"OK" isEqualToString:str3]&&deviceId!=nil){
            int msg_id = [Single sharedInstanced].msg_id;
            NSString *iotId = [deviceId stringByAppendingString:@"_123456"];
            NVLogInfo(@"step1:%@",iotId);
            [self writeDict:@{@"namespace":@"config",@"source":@"app",@"target":@"gateway",@"hw_id":deviceId,@"msg_id":@(msg_id),@"msg":@{@"CMD_CODE":AP_Shake_Step_2,@"str1":iotId,@"str2":@"",@"str3":@""}}];
            [Single sharedInstanced].msg_id++;
  
        }else if([@"bind_OK" isEqualToString:str3]&&deviceId!=nil){
            [self myRelease];
        }
        

    }

}

-(void)myRelease{
    self.isConnectCallback = nil;
    self.Callback =nil;
    self.clientSocket = nil;
    self.wifi = nil;
    self.pwd = nil;
    self.count = 0;
    if(_timer_connect!=nil){
        [_timer_connect invalidate];
    }
}

@end
